<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<META NAME="generator" CONTENT="http://txt2tags.sf.net">
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
<LINK REL="stylesheet" TYPE="text/css" HREF="style.css">
<TITLE>Another Checkers Game</TITLE>
</HEAD>
<BODY>

<DIV CLASS="header" ID="header">
<H1>Another Checkers Game</H1>
<H2>Guia para programadores</H2>
<H3>0.1</H3>
</DIV>

<DIV CLASS="toc" ID="toc">
  <UL>
  <LI><A HREF="#toc1">Introducción</A>
    <UL>
    <LI><A HREF="#toc2">Funcionalidad</A>
      <UL>
      <LI><A HREF="#toc3">Bucle principal</A>
      </UL>
    <LI><A HREF="#toc4">Propuesta para comer fichas</A>
      <UL>
      <LI><A HREF="#toc5">Como resolver caminos</A>
      </UL>
    </UL>
  </UL>

</DIV>
<DIV CLASS="body" ID="body">
<A NAME="toc1"></A>
<H1>Introducción</H1>
<P>
Este documento es una reseña breve del funcionamiento del juego
<I>Another Checkers Game</I>. Se utiliza como punto de partida para
nuevos programadores y para investigar la forma de mejorar su
funcionalidad.
</P>
<P>
Si quiere realizar cambios en el código del programa le recomendamos
leer este documento y consultar el código a la vez; dado que ambos
tratan sobre la misma estrategia pero en diferente profundidad.
</P>
<A NAME="toc2"></A>
<H2>Funcionalidad</H2>
<A NAME="toc3"></A>
<H3>Bucle principal</H3>
<P>
Como se busca que el videojuego sea totalmente interactivo, mostrando
animaciones o transiciones, se ha optado por actualizar la pantalla
de juego en base a un bucle, como en los juegos de acción.
</P>
<P>
El objeto encargado de contener al bucle principal es <CODE>World</CODE>, este objeto
contiene el método <CODE>loop</CODE> y una referencia a un objeto <CODE>Clock</CODE> para
mantener la velocidad constante en diferentes equipos.
</P>
<P>
En la jerarquía de objetos, <CODE>World</CODE> es responsable de actualizar la
pantalla, mantener la velocidad constante del juego y propagar eventos.
</P>
<P>
El siguiente diagrama muestra el orden de las llamadas e interacción
entre objetos del bucle principal:
</P>
<P>
<IMG ALIGN="middle" SRC="ima/loop.png" BORDER="0" ALT="">
</P>
<P>
La mayor parte del comportamiento del programa se encuentra inspeccionando
el método <CODE>send_event</CODE> de la clase <CODE>Mouse</CODE>.
</P>
<H4>Caso de ejemplo: Al pulsar el botón del mouse</H4>
<P>
Cuando el objeto <CODE>Mouse</CODE> recibe la notificación del evento
<CODE>MOUSEBUTTONDOWN</CODE> intercambia mensajes con los objetos de la
pantalla, y en caso de que alguno de estos componentes se
pueda arrastrar, entonces lo almacena internamente.
</P>
<P>
El método interno de <CODE>Mouse</CODE> almacena en el atributo <CODE>widget_on_drag</CODE>
la referencia a la ficha que espera comenzar a mover.
</P>
<P>
<IMG ALIGN="middle" SRC="ima/mouse_down.png" BORDER="0" ALT="">
</P>
<P>
Siguiendo el diagrama anterior, imagine una situación donde el usuario
hace <CODE>click</CODE> sobre una ficha. El objeto <CODE>World</CODE> envía el mensaje
<CODE>send_event</CODE> a <CODE>Mouse</CODE>. <CODE>Mouse</CODE> detecta que ha seleccionado una
ficha cuando le responde <CODE>GUI</CODE> le devuelve una instancia a objeto
<CODE>Checker</CODE>.
</P>
<P>
Luego, <CODE>Mouse</CODE> busca conocer a que posiciones podrá mover esa pieza. Para
ello sirve la llamada al método <CODE>get_path</CODE> del objeto <CODE>Table</CODE>.
</P>
<P>
La respuesta de <CODE>Table</CODE> menciona todas las posiciones en donde podrá
colocar esta pieza en caso de realizar un movimiento. Es importante observar
la estructura de este valor. Es una lista con todos los casilleros que puede
utilizar.
</P>
<P>
A continuación se muestran algunos ejemplos:
</P>
<P>
Si la pieza solo puede avanzar a dos casilleros vacíos:
</P>
<PRE>
[[(4, 5)], [(4, 7)]]
</PRE>
<P></P>
<P>
Si solo puede avanzar a uno (similar al anterior pero (4, 7)
está ocupada:
</P>
<PRE>
[[(4, 5)]]
</PRE>
<P></P>
<P>
Si está en una situación similar a las anteriores, pero una
pieza en la posición (3, 4) se puede comer. La repuesta
podría ser de la siguiente forma:
</P>
<PRE>
[[(4, 5), (3, 4)], [(4, 7)]]
</PRE>
<P></P>
<P>
Es decir, la lista tiene tantos elementos como caminos posibles. Cada
camino está representado en una lista de casilleros. Cada casillero
está representado por dos números: una fila y una columna.
</P>
<P>
La siguiente imagen muestra cómo están enumeradas cada una de las
celdas del tablero:
</P>
<P>
<IMG ALIGN="middle" SRC="ima/tablero.png" BORDER="0" ALT="">
</P>
<P>
Dentro del juego resultan útiles las dos numeraciones, note que las
celdas que se pueden ocupar se identifican por un solo número. Mientras
todas las posiciones de la tabla, independientemente de si se pueden
utilizar o no, se identifican por tuplas de la forma (fila, columna).
</P>
<H4>Caso de ejemplo: Al mover el mouse</H4>
<P>
Realiza una tarea similar al evento de pulsar el <CODE>Mouse</CODE>, solo
que aquí el evento se utiliza para transmitir significado visual
al jugador.
</P>
<P>
Cuando el usuario mueve el mouse, en todo momento se consulta si
hay un objeto debajo del cursor, y en caso afirmativo, se consulta
al objeto que se encuentra bajo el cursor si éste es un objeto que
se puede <I>pulsar</I> (atributo <CODE>can_click</CODE>) o <I>arrastrar</I> (atributo
<CODE>can_drag</CODE>). Estas consultas se realizan para alternar el cursor
del mouse conforme a estas situaciones. Por ejemplo, si el objeto
se puede pulsar como un botón, el puntero del mouse se convierte
en un cursor activo, en caso contrario se coloca un puntero de
mouse traducional.
</P>
<P>
<IMG ALIGN="middle" SRC="ima/mouse_motion.png" BORDER="0" ALT="">
</P>
<P>
Si el objeto <CODE>Mouse</CODE> ya ha detectado con anterioridad la
pulsación sobre un elemento entonces comienza a arrastrarlo.
</P>
<A NAME="toc4"></A>
<H2>Propuesta para comer fichas</H2>
<A NAME="toc5"></A>
<H3>Como resolver caminos</H3>
<P>
El jugador solo podrá realizar el mejor movimiento
permitido. Para asegurar esta funcionalidad se
sigue la siguiente estrategia:
</P>
<H4>Al iniciar el turno</H4>
  <UL>
  <LI>Recorrer todas las fichas del jugador que tiene turno.
    <UL>
    <LI>Recolectar todos los caminos posibles para cada una de estas fichas.
    <LI>Seleccionar solo los mejores movimientos de las mejores fichas.
    <LI>Almacenar el resultado de la anterior en un diccionario de Table.
    </UL>
  </UL>

<P>
Así, cuando el jugador inicia su turno, ya se creará un diccionario
con los mejores movimientos para realizar.
</P>
<P>
Este diccionario tendrá la siguiente apariencia:
</P>
<PRE>
{
&lt;Piece instance&gt;: [[(1, 2)], [(2, 3)]],
&lt;Piece instance&gt;: [[(2, 3)], [(2, 5)]]
}
</PRE>
<P></P>
<P>
Note que solo encontrará caminos para los mejores movimientos, si un
jugador puede mover 5 fichas, pero solo con 2 realiza los mejores
movimientos, entonces el diccionario solo tendrá 2 elementos.
</P>
<H4>Cuando el usuario pasa con el mouse sobre la ficha</H4>
<P>
En una segunda instancia, se consulta el diccionario para saber
que movimientos se permiten.
</P>
  <UL>
  <LI>si la pieza no está dentro del diccionario, no dejará moverla.
  <LI>si la pieza está en el diccionario:
  </UL>

<P>
Estas decisiones se verán en la interfaz del juego, si no se permite
mover una ficha el cursor del mouse mostrará una marca roja, y cuando
se pueda mover el mouse tendrá una marca verde:
</P>
<P>
<IMG ALIGN="middle" SRC="ima/cursores.png" BORDER="0" ALT="">
</P>
<H4>Cuando el usuario suelta la pieza</H4>
  <UL>
  <LI>¿ el camino tiene elementos pares ?:
    <UL>
    <LI>SI:
      <UL>
      <LI>significa que tiene que comer en la primer posición. Así que tiene que
        eliminar al enemigo de esa posición.
      <LI>luego tiene que mover a la siguiente posición de donde comió.
      <LI>tiene que eliminar del camino a las dos posiciones en donde avanzó.
      </UL>
    <LI>NO:
      <UL>
      <LI>deja mover la pieza solamente a los primeros casilleros de los caminos.
      <LI>quita el primer elemento de este camino.
      </UL>
    </UL>
  <LI>¿ la lista de camino está vacía ?
    <UL>
    <LI>SI:
      <UL>
      <LI>dar el turno al otro jugador.
      </UL>
    <LI>NO:
      <UL>
      <LI>retener el turno y quedar en el estado "cuando el usuario pasa con el
        mouse sobre la ficha".
      </UL>
    </UL>
  </UL>

</DIV>

<!-- html code generated by txt2tags 2.3 (http://txt2tags.sf.net) -->
<!-- cmdline: txt2tags -\-css-sugar -\-encoding utf-8 -\-toc -t html -\-style style.css como_funciona.t2t -->
</BODY></HTML>
